//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ScientificWorkflow.SecurityControls
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    using Microsoft.Research.ScientificWorkflow.TridentModel;
    using Microsoft.Research.ScientificWorkflow.UIDesigner;
    using Microsoft.Research.DataLayer;
    using Microsoft.Research.eResearch.Common.Linq;
    
    /// <summary>
    /// Interaction logic for UsersAndGroupsPicker.xaml
    /// </summary>
    public partial class UsersAndGroupsPicker : Window
    {
        /// <summary>
        /// Security principals.
        /// </summary>
        private Collection<SecurityPrincipalModel> usersAndGroups = new Collection<SecurityPrincipalModel>();

        /// <summary>
        /// Gets or sets the users and groups.
        /// </summary>
        /// <value>The users and groups.</value>
        public Collection<SecurityPrincipalModel> UsersAndGroups
        {
            get
            {
                return this.usersAndGroups;
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="UsersAndGroupsPicker"/> is cancelled.
        /// </summary>
        /// <value><c>true</c> if cancelled; otherwise, <c>false</c>.</value>
        public bool Canceled { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="UsersAndGroupsPicker"/> class.
        /// </summary>
        public UsersAndGroupsPicker(IEnumerable<ISecurityPrincipal> usersAndGroupsSet)
        {
            InitializeComponent();
            if (usersAndGroupsSet != null)
            {
                Collection<SecurityPrincipalModel> tempColl = new Collection<SecurityPrincipalModel>();
                usersAndGroupsSet.ForEach(principal => tempColl.Add(new SecurityPrincipalModel(principal)));
                tempColl.OrderBy(item => item.SecurityPrincipalModelType).OrderBy(item => item.DisplayName).ForEach(item => this.UsersAndGroups.Add(item));

                this.usersAndGroupsListView.ItemsSource = this.UsersAndGroups;
                ICollectionView view = CollectionViewSource.GetDefaultView(this.UsersAndGroups);
                new TextSearchFilter(view, this.txtBxSearch);
            }
        }
        
        /// <summary>
        /// The event handler for the Ok button click.
        /// </summary>
        /// <param name="sender">The origin of the event.</param>
        /// <param name="e">The event arguments.</param>
        private void OkButtonClick(object sender, RoutedEventArgs e)
        {
            this.Canceled = false;
            this.Close();
        }

        /// <summary>
        /// The event handler for the cancel/close button click.
        /// </summary>
        /// <param name="sender">The origin of the event.</param>
        /// <param name="e">The event arguments.</param>
        private void CancelButtonClick(object sender, RoutedEventArgs e)
        {
            this.Canceled = true;
            this.Close();
        }

        /// <summary>
        /// The event handler for the left mouse button down on the main border. Used to drag window.
        /// </summary>
        /// <param name="sender">The origin of the event.</param>
        /// <param name="e">The event arguments.</param>
        private void BorderMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }
    }

    /// <summary>
    /// Helper class for text filtering.
    /// </summary>
    public class TextSearchFilter
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="TextSearchFilter"/> class.
        /// </summary>
        /// <param name="filteredView">The filtered view.</param>
        /// <param name="textBox">The text box.</param>
        public TextSearchFilter(ICollectionView filteredView, TextBoxWatermark textBox)
        {
            string filterText = string.Empty;
            filteredView.Filter = delegate(object obj)
            {
                if (textBox.IsWatermarked)
                    return true;

                if (string.IsNullOrEmpty(filterText))
                    return true;

                string name = string.Empty;
                SecurityPrincipalModel securityPrincipalModel = obj as SecurityPrincipalModel;
                if (securityPrincipalModel != null)
                {
                    name = securityPrincipalModel.DisplayName;
                }

                if (string.IsNullOrEmpty(name))
                    return false;

                int index = name.IndexOf(filterText, 0, StringComparison.OrdinalIgnoreCase);
                return index > -1;
            };

            textBox.TextChanged += delegate
            {
                filterText = textBox.Text;
                filteredView.Refresh();
            };
        }
    }
}
